import {Computed, Hook, Mut, VueService} from 'vue3-oop'
import { h } from 'vue'
import {Injectable} from "injection-js";
import {MenuOption} from "naive-ui";
import { nicon } from "@/utils/IconUtil";
import menus from './menus';

@Injectable()
export default class AppService extends VueService {
  static instCount = 0;

  @Mut() collapsed = false;
  @Mut() drawerActive = false;

  @Mut() mainMenu = [] as any[];
  @Mut() mainExpended = [] as string[];
  @Mut() mainTabs = [] as any[];

  constructor(
  ) {
    super();
    AppService.instCount++>1 && console.error("AppSercice.instCount="+AppService.instCount);
    watch(()=>window.$router.currentRoute.value.fullPath,this.openTab);
  }

  toggleDrawer=()=>{
    this.drawerActive = !this.drawerActive
  }
  toggleCollapsed=()=>{
    this.collapsed = !this.collapsed
  }

  private toMenuOption=(menuItem:any):MenuOption=>{
    let label = ()=>menuItem.label;
    if(menuItem.url&&menuItem.url.length>0){
      const url = this.completeUrl(menuItem.url,menuItem.urlArgs,{...menuItem.hashArgs,menu:menuItem.key});
      label = ()=>h('a',{href:url,target:menuItem.target||'_self'},menuItem.label);
    }
    return {
      key: menuItem.key,
      label: label,
      icon: nicon(menuItem.icon),
      disabled: menuItem.disabled,
      children: (menuItem.children && menuItem.children.length>0)?menuItem.children.map((item: any)=>this.toMenuOption(item)):null
    } as MenuOption;
  }

  @Computed()
  get mainMenuOptions():MenuOption[] {
    return this.mainMenu.map(item=>this.toMenuOption(item));
  }

  @Computed()
  get mainMenuBread(){
    const activeKey = window.$router.currentRoute.value.query['menu'] as string;
    const findChildren = (menus:MenuOption[],activeKey:string):any[]=>{
      for(let menu of menus){
        if(menu.key===activeKey){
          return [{icon:menu.icon, label:menu.label}];
        }else if(menu.children){
          const childArr = findChildren(menu.children,activeKey);
          if(childArr.length>0){
            return [{icon:menu.icon, label:menu.label},...childArr];
          }
        }
      }
      return [];
    }
    return findChildren(this.mainMenuOptions,activeKey);
  }

  private completeUrl=(src:string,urlArgs:any,hashArgs:any)=>{
    let urlArgStr = '';
    for(let p in urlArgs){
      let temp = p+'='+encodeURIComponent(urlArgs[p]);
      urlArgStr = urlArgStr.length>0?(urlArgStr+'&'+temp):temp;
    }
    let hashArgStr = '';
    for(let p in hashArgs){
      let temp = p+'='+encodeURIComponent(hashArgs[p]);
      hashArgStr = hashArgStr.length>0?(hashArgStr+'&'+temp):temp;
    }
    let pieces = src.split('#',2);
    pieces[0] += urlArgStr.length==0?'': (pieces[0].indexOf('?')>0?'&':'?'+urlArgStr);
    if(pieces[1]){
      pieces[1] += hashArgStr.length==0?'':(pieces[1].indexOf('?')>0?'&':'?'+hashArgStr);
    }
    return pieces.join('#');
  }

  @Hook('Mounted')
  onMounted(){
    this.mainMenu = menus;
    const mainExpendedStr = localStorage.getItem("mainExpended")
    if(mainExpendedStr && mainExpendedStr.length>0){
      this.mainExpended = mainExpendedStr.split(",");
    }
    const mainTabsStr = localStorage.getItem("mainTabs");
    if(mainTabsStr && mainTabsStr.length>0){
      this.mainTabs = JSON.parse(mainTabsStr).map((item:any)=>{
        return {
          name: item.name,
          path: item.path,
          pinned: true,
          active: false,
        }
      })
    }
  }

  // 打开标签页
  openTab=()=>{
    const name = window.$router.currentRoute.value.meta.title||"新标签";
    const path = window.$router.currentRoute.value.fullPath;
    const ignoreTab = window.$router.currentRoute.value.meta.ignoreTab;
    const oldTab = this.mainTabs.find(item=>item.path===path);
    this.mainTabs.forEach(item=>{item.active=false});
    if(oldTab){
      oldTab.active=true;
    }else if(!ignoreTab){
      this.mainTabs.push({
        name: name,
        path: path,
        pinned: false,
        active: true
      });
    }
  }

  // 关闭标签页
  closeTab=(index:number)=>{
    const tocloseTab = this.mainTabs.splice(index,1)[0];
    if(tocloseTab && tocloseTab.active){
      if(index>0){
        const path = this.mainTabs[index-1].path
        setTimeout(()=>{window.$router.push(path)},50);
      }else if(index<this.mainTabs.length-1){
        const path = this.mainTabs[index+1].path
        setTimeout(()=>{window.$router.push(path)},50);
      }else{
        window.location.href="/";
      }
    }
  }

  // 刷新标签页
  refreshTab=(index:number)=>{
    // TODO
    window.$router.go(0);
  }

  // 开关标签页固定
  toggleTabPinned=(index:number)=>{
    this.mainTabs[index].pinned = !this.mainTabs[index].pinned;
    const mainTabs = [] as any[];
    this.mainTabs.forEach((item)=>{
      item.pinned && mainTabs.push({name: item.name, path: item.path});
    })
    localStorage.setItem("mainTabs",JSON.stringify(mainTabs));
  }

  // 关闭其他标签页（除了固定的）
  closeOtherTabs=(index:number)=>{
    this.mainTabs = this.mainTabs.filter((item,idx)=>item.pinned||idx===index);
    const activeTab = this.mainTabs.find((item)=>item.active);
    if(this.mainTabs.length===0){
      window.location.href="/";
    }else if(!activeTab){
      window.$router.push(this.mainTabs[this.mainTabs.length-1].path);
    }
  }

  // 关闭所有标签页（除了固定的）
  closeAllTabs=()=>{
    this.mainTabs = this.mainTabs.filter((item)=>item.pinned);
    const activeTab = this.mainTabs.find((item)=>item.active);
    if(this.mainTabs.length===0){
      window.location.href="/";
    }else if(!activeTab){
      window.$router.push(this.mainTabs[this.mainTabs.length-1].path);
    }
  }

  setMainExpended=(keys:string[])=>{
    this.mainExpended = keys;
    localStorage.setItem("mainExpended",keys.join(","));
  }

}
